// keel_awtcx.cpp : Defines the exported functions for the DLL application.
//

#include "stdafx.h"

#include "CJawt.h"
#include "backstage_awt_AWTGLContextWindowsImpl.h"

HGLRC g_cont;
jlong g_pf;

JNIEXPORT jlong JNICALL Java_backstage_awt_AWTGLContextWindowsImpl__1createContext(JNIEnv *env,jobject,jlong pf,jobject glcanvas)
{
	//env->GetObjectClass(glcanvas);

	if ( g_pf )
		pf = g_pf;
	if ( pf == 0)
		return 0;

	CJawt cjawt;
	if (!cjawt.init(env,glcanvas))
		return 0;

	wglMakeCurrent(NULL,NULL);
	PIXELFORMATDESCRIPTOR ppfd;
	DescribePixelFormat(cjawt.getHDC(),pf,sizeof(ppfd),&ppfd);
	if(!SetPixelFormat(cjawt.getHDC(),pf,&ppfd))
		return 0;

	HGLRC cont=wglCreateContext(cjawt.getHDC());
	if(!wglMakeCurrent(cjawt.getHDC(),cont))
	{
		wglDeleteContext(cont);
		wglMakeCurrent(NULL,NULL);
		return 0;
	}

	if (g_cont)
	{
		if(!wglShareLists(g_cont,cont))
		{
			wglDeleteContext(cont);
			wglMakeCurrent(NULL,NULL);
			return 0;
		}
	}
	else
		g_cont=cont;

	return reinterpret_cast<jlong>(cont);
}

JNIEXPORT void JNICALL Java_backstage_awt_AWTGLContextWindowsImpl__1deleteContext( JNIEnv *, jobject, jlong cont)
{
	wglMakeCurrent(NULL,NULL);
	wglDeleteContext(reinterpret_cast<HGLRC>(cont));
}

jobject CreatePixelFormat(JNIEnv *env, HDC hdc, jlong &i)
{
	PIXELFORMATDESCRIPTOR ppfd;
	while(ZeroMemory(&ppfd,sizeof(ppfd)),
		ppfd.nSize = sizeof(ppfd),
		ppfd.nVersion = 1,
		DescribePixelFormat(hdc, ++i, sizeof(ppfd), &ppfd))
	{
		if((!(ppfd.dwFlags & PFD_GENERIC_FORMAT) || (ppfd.dwFlags & PFD_GENERIC_ACCELERATED))
			&& !(ppfd.dwFlags & PFD_DRAW_TO_BITMAP)
			&& ppfd.dwFlags & PFD_DOUBLEBUFFER
			&& ppfd.iPixelType != 1)
		{
			if(ppfd.cDepthBits)
				g_pf=i;

			jclass pf = env->FindClass("keel/gfx/PixelFormat");
			jmethodID pf_init = env->GetMethodID(pf, "<init>", "(JIIIIIIIIIIII)V");
			return env->NewObject(pf, pf_init, i,ppfd.cColorBits,
				ppfd.cRedBits,ppfd.cGreenBits,ppfd.cBlueBits,ppfd.cAlphaBits,ppfd.cDepthBits,
				ppfd.cAccumBits,ppfd.cAccumRedBits,ppfd.cAccumGreenBits,ppfd.cAccumBlueBits,
				ppfd.cAccumAlphaBits,ppfd.cStencilBits);
		}
	}

	return NULL;
}

JNIEXPORT jobjectArray JNICALL Java_backstage_awt_AWTGLContextWindowsImpl__1getPixelFormatList( JNIEnv *env, jobject, jobject glcanvas)
{
	CJawt cjawt;
	if(cjawt.init(env,glcanvas))
	{
		jobject pfList[50];

		jlong i=0;
		int n=0;
		while(n<50)
		{
			pfList[n]=CreatePixelFormat(env,cjawt.getHDC(),i);
			if(pfList[n++]==NULL)
				break;
		}

		jclass pf = env->FindClass("keel/gfx/PixelFormat");
		jobjectArray ret=env->NewObjectArray(n,pf,NULL);
		for(int j=0;j<n;++j)
			env->SetObjectArrayElement(ret,j,pfList[j]);
		return ret;
	}
	
	return NULL;
}

JNIEXPORT jboolean JNICALL Java_backstage_awt_AWTGLContextWindowsImpl__1makeCurrent( JNIEnv *env, jobject, jlong cont, jobject glcanvas)
{
	CJawt cjawt;
	if(cjawt.init(env,glcanvas))
	{
		return wglMakeCurrent(cjawt.getHDC(),reinterpret_cast<HGLRC>(cont)); 
	}
	return FALSE;
}

JNIEXPORT void JNICALL Java_backstage_awt_AWTGLContextWindowsImpl__1free( JNIEnv *env, jobject, jlong, jobject )
{
	wglMakeCurrent(NULL,NULL);
}

JNIEXPORT void JNICALL Java_backstage_awt_AWTGLContextWindowsImpl_swapBuffers( JNIEnv *env, jobject, jlong, jobject glcanvas)
{
	CJawt cjawt;
	if(cjawt.init(env,glcanvas))
	{
		SwapBuffers(cjawt.getHDC());
	}
}

